package futbol.tacticas.concursantes.TacticaAmingos;

import futbol.tacticas.concursantes.Tactica;
import java.awt.*;
import java.util.*;
import futbol.tacticas.*;
/**
 *
 * @author Pitxardo
 */

public class TacticaAmingos implements Tactica{
    
    Point bola_vieja;
    Point bola;
    
    int zonax = 32; //20;		//16
    int zonay = 24; //15;		//12
    int zonasub = 10; //16;	//20
    
    int[][] zonas = new int[zonax][zonay];
    //Modificado por la organizacion. Si no almacenará información de partidos anteriores.
    //static ArrayList<nodo> abiertos = new ArrayList<nodo>();
	//static ArrayList<nodo> cerrados = new ArrayList<nodo>();
    ArrayList<nodo> abiertos = new ArrayList<nodo>();
	ArrayList<nodo> cerrados = new ArrayList<nodo>();

	int buscax, buscay;
	int posjx, posjy;
	
    int[] cubre = new int[11];
    
    int tiempo=0;
    
    /** Creates a new instance of TacticaCobian */
    public TacticaAmingos() {
    }
    
    private int nValores[][]={
        {-155,0,6}, // Portero
        
        {-90,30,6}, // Defensa Lateral [1]
        {-110,70,6}, // Defensa Central [2]
        {-110,-70,6}, // Defensa Central [3]
        {-90,-30,6}, // Defensa Lateral [4]
        
        {-60,0,4}, // Centrocampista defensivo[5]
        {0,60,4}, // Centrocampista lateral [6]
        {0,-60,4}, // Centrocampista lateral [7]
        
        {-40,0,7}, // Libero[8]
        {70,-20,7}, // Delantero[9]
        {70,20,7} // Delantero[10]
        
    };

    public String getNombre() {
        return "Amingos Unidos";
    }

    public Color getColor1() {
    	return new Color(255,0,0);
    }

    public Color getColor2() {
    	return new Color(0,0,0);
    }

    public Color getColorNumero() {
    	return new Color(255,255,255);
    }

    public int getFuerza(int n) {
        return nValores[n][2];
    }

    public int getXInicial(int n) {
        return nValores[n][0];
    }

    public int getYInicial(int n) {
        return nValores[n][1];
    }
    

    public Vector<Comando> getComandos(SituacionJugadores sj){
        
        Vector<Comando> com=new Vector();
        
        // Actualizar bolas
        bola_vieja = bola;
        bola=sj.getBola();

        // Obtener lista de jugadores
        Point jugadores[]=sj.getMisJugadores();
        Point contrarios[]=sj.getContrario();
        
        // Obtener informacion de la bola
        actualizar_matriz(contrarios);
        double velocidad = 0;
        if(tiempo!=0) velocidad = obtenerVelocidadBalon();
        double[] caera = new double[2];
        if(tiempo!=0) caera = pos_frenada15(velocidad);
        double[] caera2 = new double[2];
        if(tiempo!=0) caera2 = pos_frenada0(velocidad);
        
        
        //Posicionamiento
        for (int n=0;n<11;n++) {
            com.add(new ComandoIrA(n,nValores[n][0],nValores[n][1]));
            if(n>1)
            	com.add(new ComandoIrA(n,nValores[n][0]+(bola.getX()/4),nValores[n][1]));
            cubre[n]=-1;
        }
        
        // Portero
        if(tiempo!=0) actua_portero(com, sj);
        pasar_balon(0, com, jugadores, contrarios, sj);
        
        
        // Defendiendo
        int nJug = sj.getMasCercanoDeBola();
        //for(int i=0; i<11; i++)
    	//	cubre[i]=-1;
        
        marcar(jugadores, contrarios);
        
        for(int i=1; i<11; i++) {
        	
        	if((i==sj.getMiJugadorMasCerca(caera[0],caera[1]) && velocidad>14) || (i==nJug && velocidad<15)) { //|| ( && futbol.General.getDistancia(jugadores[i].x, jugadores[i].y, nValores[i][0], nValores[i][1])<75 && futbol.General.getDistancia(jugadores[nJug].x, jugadores[nJug].y, bola.getX(), bola.getY())>20 ) ) { // && velocidad<14)) {
        		//desmarcar(i);
        		com.add(new ComandoIrA(i,caera[0],caera[1]));
        		if(velocidad<15) { 
        			com.add(new ComandoIrA(i,caera2[0],caera2[1]));
        			if(futbol.General.getDistancia(jugadores[i].x, jugadores[i].y, bola.getX(), bola.getY())<40)
        				com.add(new ComandoIrA(i,bola.getX(),bola.getY()));
        		}
        	} else {
        		// Los NO delanteros cubren al contrario si esta cerca de su zona
        		if(i<8) {
        			int cJ=-1;
        			for(int k=0; k<11; k++)
        				if(cubre[k]==i) cJ=k;
        			if(cJ!=-1) {
        				double x3 = bola.getX() - contrarios[cJ].getX();
        		        double y3 = bola.getY() - contrarios[cJ].getY();
        		        double n = Math.sqrt(Math.pow(x3,2)+Math.pow(y3,2));
        		        double nx = contrarios[cJ].getX()+(x3/n)*20;
        		        double ny = contrarios[cJ].getY()+(y3/n)*20;
        		        com.add(new ComandoIrA(i,(int)nx,(int)ny)); 
        			}
        		}
        		
        		if(i>7) {
            		//if(futbol.General.getDistancia(jugadores[i].x, jugadores[i].y, nValores[i][0], nValores[i][1])<30) {
            		if(bola.getX()>0) {
            			if(i==9 && bola.getY()<0) com.add(new ComandoIrA(i,bola.getX(),bola.getY()));
            			if(i==10 && bola.getY()>0) com.add(new ComandoIrA(i,bola.getX(),bola.getY()));
            		} else {
            			if(i==9) com.add(new ComandoIrA(9,jugadores[8].x+100,nValores[9][1]));
            			if(i==10) com.add(new ComandoIrA(10,jugadores[8].x+100,nValores[10][1]));
            		}
            	}
        		
        	}

        }
        
        if(futbol.General.getDistancia(jugadores[8].x, jugadores[8].y, nValores[8][0], nValores[8][1])<30) {
			com.add(new ComandoIrA(8,bola.getX(),bola.getY()));
		}
             
        // Regatear
        if(futbol.General.getDistancia(jugadores[nJug].x, jugadores[nJug].y, bola.getX(), bola.getY())<15) {
        	int hacia = 1;
        	int fuerzag = 30;
        	int x1 = (jugadores[nJug].x+160)/zonasub;
        	int y1 = (jugadores[nJug].y+120)/zonasub;
        	if(nJug>7) fuerzag=10;
        	if(nJug<5) fuerzag=12;
        	posjx = x1;
        	posjy = y1;
        	if(x1<0) x1=0;
        	if(x1>zonax-1) x1=zonax-1;
        	if(y1<0) y1=0;
        	if(y1>zonay-1) y1=zonay-1;
        	 
        	buscax=((160)/zonasub)+1; //zonax-1;
        	if(jugadores[nJug].x>0) buscax=zonax-1;
    		if(jugadores[nJug].y<0) 
    			buscay=0;
    		else
    			buscay=zonay-1;
    		
    		//System.out.println("Quiero un nuevo camino!!! ("+x1+","+y1+")");
    		hacia = buscarCamino(x1,y1);
        	if(hacia==1) com.add(new ComandoGolpearBola(nJug,jugadores[nJug].x+fuerzag,jugadores[nJug].y));
        	else if(hacia==2) com.add(new ComandoGolpearBola(nJug,jugadores[nJug].x+fuerzag,jugadores[nJug].y+fuerzag));
        	else if(hacia==3) com.add(new ComandoGolpearBola(nJug,jugadores[nJug].x,jugadores[nJug].y+fuerzag));
        	else if(hacia==4) com.add(new ComandoGolpearBola(nJug,jugadores[nJug].x-fuerzag,jugadores[nJug].y+fuerzag));
        	else if(hacia==5) com.add(new ComandoGolpearBola(nJug,jugadores[nJug].x-fuerzag,jugadores[nJug].y));
        	else if(hacia==6) com.add(new ComandoGolpearBola(nJug,jugadores[nJug].x-fuerzag,jugadores[nJug].y-fuerzag));
        	else if(hacia==7) com.add(new ComandoGolpearBola(nJug,jugadores[nJug].x,jugadores[nJug].y-fuerzag));
        	else if(hacia==8) com.add(new ComandoGolpearBola(nJug,jugadores[nJug].x+fuerzag,jugadores[nJug].y-fuerzag));
        	else if(hacia==-1) {
        		pasar_balon(nJug, com, jugadores, contrarios, sj);
        	}
        	//System.out.println("Hacia: "+hacia);
        	//delayMilli(2000);
        	
        	if(nJug<8) pasar_balonAlante(nJug, com, jugadores, contrarios, sj);
        	
        	if(nJug<8 && futbol.General.getDistancia(jugadores[nJug].x, jugadores[nJug].y, 0, 0)<80) {
        		if(linea_libre(jugadores[nJug].x, jugadores[nJug].y, jugadores[8].x, jugadores[8].y, contrarios)) {
        			com.add(new ComandoPase(nJug,8));
        		}
        	}
        	
        }
        
        // Contrario demasiado cerca del balon
        int l=0;
        boolean peligro=false;
        while(l<11 && peligro==false) {
        	if(futbol.General.getDistancia(contrarios[l].x, contrarios[l].y, bola.getX(), bola.getY())<18) {
        		for(int i=0;i<11;i++)
        			pasar_balon(i, com, jugadores, contrarios, sj);
        		peligro=true;
        	}
        	l++;
        }
        
        // Ataque
        for(int i=1;i<11;i++) {
        	if(jugadores[i].x>20) {
        		//if(i>8) {
        			//if(jugadores[i].x>50) com.add(new ComandoTiroAPuerta(i,0));
        		if(i<9) {
      				if(jugadores[i].x>120) pasar_balon(i, com, jugadores, contrarios, sj);
      				if(futbol.General.getDistancia(jugadores[i].x, jugadores[i].y, jugadores[10].x, jugadores[10].y)<40) {
      	        		if(linea_libre(jugadores[i].x, jugadores[i].y, jugadores[10].x, jugadores[10].y, contrarios)) {
      	        			com.add(new ComandoPase(i,10));
      	        		}
      	        	} else if(futbol.General.getDistancia(jugadores[i].x, jugadores[i].y, jugadores[9].x, jugadores[9].y)<40) {
      	        		if(linea_libre(jugadores[i].x, jugadores[i].y, jugadores[9].x, jugadores[9].y, contrarios)) {
      	        			com.add(new ComandoPase(i,9));
      	        		}
      	        	}
        		}
        	}
        }
        
        com.add(new ComandoTiroAPuerta(8,0));
        com.add(new ComandoTiroAPuerta(9,0));
        com.add(new ComandoTiroAPuerta(10,0));
     
        //System.out.println("Angulo calculado: "+angulo);
        //System.out.println("Calculo ("+caera[0]+","+caera[1]+")");
        //if(velocidad>14 && velocidad<=15)
        //	System.out.println(" - Esta en ("+bola.getX()+","+bola.getY()+")");
        //System.out.println(" - Ahora ("+bola.getX()+","+bola.getY()+")");
        
        
        tiempo++;
        
        return com;
    }
    
    
    
    
    // COMPORTAMIENTO PORTERO
    private void actua_portero(Vector<Comando> com, SituacionJugadores sj) {
        // PORTERO
        if(bola.getX()-bola_vieja.getX()<0) {
            double y=dondeIraY();
            if (y<-30) y=-30;
            if (y>30) y=30;
            com.add(new ComandoIrA(0,nValores[0][0], y));
        } else {
            if(bola.getX()<-110 && bola.getY()<60 && bola.getY()>-60) {
                int nJug=sj.getMasCercanoDeBola();
                if(nJug==0) com.add(new ComandoIrA(nJug,bola.getX(), bola.getY()));
            } else {
                //if(bola.getX()<-110) {
                    double y=bola.getY();
                    if (y<-30) y=-30;
                    if (y>30) y=30;
                    com.add(new ComandoIrA(0,nValores[0][0], y));
                //}
            }
        }
        com.add(new ComandoGolpearBola(0,0,120));
    }
    
  
    
    private void pasar_balon(int j1, Vector<Comando> com, Point jugadores[], Point contrarios[], SituacionJugadores sj) {
    	int j2=-1;
    	double mejor_pos=9999;
    	for(int i=0; i<11; i++) {
    		if(i!=j1) {
    			double dista = futbol.General.getDistancia(jugadores[j1].x, jugadores[j1].y, jugadores[i].x, jugadores[i].y);
    			double mejor_provi = dista;
    			int cr = sj.getContrarioMasCerca(i);
    			double dista2 = futbol.General.getDistancia(jugadores[i].x, jugadores[i].y, contrarios[cr].x, contrarios[cr].y);
    			if(mejor_provi<mejor_pos && dista2>10 && dista>30 && jugadores[i].x>(jugadores[j1].x-60)) {
    				if(j1>7 || linea_libre(jugadores[j1].x, jugadores[j1].y, jugadores[i].x, jugadores[i].y, contrarios)==true) {
    					mejor_pos = mejor_provi;
    					j2 = i;
    				}
    			}
    		}
    	}
    	
    	if(j2!=-1 && j1<9)
    		com.add(new ComandoPase(j1,j2));
    	else if(j1==8) {
    		com.add(new ComandoPase(j1,10));
    	} else {
    		//com.add(new ComandoGolpearBola(j1,jugadores[j1].x,jugadores[j1].y+30));
    		com.add(new ComandoPase(j1,9));
    	}
    	    	
    }
    
    
    private void pasar_balonAlante(int j1, Vector<Comando> com, Point jugadores[], Point contrarios[], SituacionJugadores sj) {
    	int j2=-1;
    	double mejor_pos=9999;
    	for(int i=0; i<11; i++) {
    		if(i!=j1) {
    			
    			double dista = futbol.General.getDistancia(jugadores[j1].x, jugadores[j1].y, jugadores[i].x, jugadores[i].y);
    			double mejor_provi = dista;
    			int cr = sj.getContrarioMasCerca(i);
    			double dista2 = futbol.General.getDistancia(jugadores[i].x, jugadores[i].y, contrarios[cr].x, contrarios[cr].y);
    			
    			if(mejor_provi<mejor_pos && dista2>10 && dista>30 && dista<50 && jugadores[i].x>jugadores[j1].x) {
    				if(linea_libre(jugadores[j1].x, jugadores[j1].y, jugadores[i].x, jugadores[i].y, contrarios)==true) {
    					mejor_pos = mejor_provi;
    					j2 = i;
    				}
    			}
    			
    		}
    	}
    	
    	if(j2!=-1) com.add(new ComandoPase(j1,j2));
    	    	
    }
    
    
    
    private boolean linea_libre(double pi_1x, double pi_1y, double pf_1x, double pf_1y, Point contrarios[]) {
    	
    	double pi_2x, pi_2y, pf_2x, pf_2y;
        double a, a1, b, b1, c;
        //int x, y;

        boolean libre = true;

        for(int k=0; k<2; k++) {
        	int i=0;
        	while(i<11 && libre==true) {

        		if(k==0) {
        			pi_2x = contrarios[i].x-10;
        			pi_2y = contrarios[i].y;
        			pf_2x = contrarios[i].x+10;
        			pf_2y = contrarios[i].y;
        		} else {
        			pi_2x = contrarios[i].x;
        			pi_2y = contrarios[i].y-10;
        			pf_2x = contrarios[i].x;
        			pf_2y = contrarios[i].y+10;
        		}

        		c = (pf_2y - pi_2y)*(pf_1x - pi_1x) - (pf_2x - pi_2x)*(pf_1y - pi_1y);
        		if(c!=0) {
        			a1 = (pf_2x - pi_2x)*(pi_1y - pi_2y) - (pf_2y - pi_2y)*(pi_1x - pi_2x);
        			b1 = (pf_1x - pi_1x)*(pi_1y - pi_2y) - (pf_1y - pi_1y)*(pi_1x - pi_2x);
        			a = a1 / c;
        			b = b1 / c;

        			//x = pi_1x + a*(pf_1x - pi_1x);
        			//y = pi_1y + a*(pf_1y - pi_1y);

        			if(a>0 && a<=1 && b>0 && b<=1) libre = false;
        		}
        		i++;
        	}
        }

        return libre;
    	
    }
    
    
    // Cubriendo al jugador
    private void marcar(Point jug[], Point con[]) {
    	
    	for(int z=0; z<11; z++) {
    		int j_marcado=-1;
    		double mas_izquierda=9999;
    		for(int i=0; i<11; i++) {
    			if(cubre[i]==-1) {
    				double dista = con[i].x;
    				if(dista<mas_izquierda) {
    					mas_izquierda = dista;
    					j_marcado = i;
    				}
    			}
    		}
    		
    		if(j_marcado!=-1) {
    			int j_cerca=-1;
    			double mas_cerca=9999;
    			for(int j=1; j<8; j++) {
    				double dista = futbol.General.getDistancia(jug[j].x, jug[j].y, con[j_marcado].x, con[j_marcado].y);
    			
    				int k=1;
    				boolean esta=false;
    				while(k<11 && esta==false) {
    					if(cubre[k]==j) esta=true;
    					k++;
    				}
    				
    				if(futbol.General.getDistancia(jug[j].x, jug[j].y, bola.getX(), bola.getY())<15) esta=true;
    			
    				if(dista<mas_cerca && esta==false) {
    					mas_cerca = dista;
    					j_cerca = j;
    				}
    			}
    			if(j_cerca!=-1) cubre[j_marcado]=j_cerca;
    		}
    	}
    	
    }
    
    
    private void desmarcar(int j1) {
    	for(int i=0; i<11; i++)
    		if(cubre[i]==j1) cubre[i]=-1;
    }
    
    
    // Actualizar la matriz con las posiciones contrarias
    private void actualizar_matriz(Point contrarios[]) {
        
    	// Vaciar matriz
    	for(int i=0; i<zonax; i++)
            for(int j=0; j<zonay; j++) {
                zonas[i][j]=-1;
            }
        //System.out.println("-------- FIN DE LA LISTA ACTUAL ---------");
        
        for(int h=0; h<11; h++) {
        	int x1 = (contrarios[h].x+160)/zonasub;
        	int y1 = (contrarios[h].y+120)/zonasub;
        	if(x1<0) x1=0;
        	if(x1>zonax-1) x1=zonax-1;
        	if(y1<0) y1=0;
        	if(y1>zonay-1) y1=zonay-1;
        	zonas[x1][y1]=h;
        	
        	if(x1>0) {
        		zonas[x1-1][y1]=h;
        		if(x1>1) zonas[x1-2][y1] = h;
        		if(y1>0) zonas[x1-1][y1-1]=h;
            	if(y1<zonay-1) zonas[x1-1][y1+1]=h;
        	}
        	if(x1<zonax-1) {
        		zonas[x1+1][y1]=h;
        		if(x1<zonax-2) zonas[x1+2][y1] = h;
        		if(y1>0) zonas[x1+1][y1-1]=h;
            	if(y1<zonay-1) zonas[x1+1][y1+1]=h;
        	}
        	if(y1>0) zonas[x1][y1-1]=h;
        	if(y1<zonay-1) zonas[x1][y1+1]=h;
        	
        }
        
    }
    
    // Obtener la velocidad/hipotenusa del balon
    private double obtenerVelocidadBalon() {
        double dista = 0;
        
        double a = bola.getX() - bola_vieja.getX();
        double b = bola.getY() - bola_vieja.getY();
        dista = Math.sqrt((a*a)+(b*b));

        return dista-1;
    }
    
    // Calcular donde parara la bola
    private double[] pos_frenada15(double velocidad) {
    	double angulo = futbol.General.getAngulo(bola_vieja.getX(), bola_vieja.getY(), bola.getX(), bola.getY());
        double x1 = bola.getX();
        double y1 = bola.getY();
        double[] donde_caera = new double[2];
        
        for(int i=15; i<velocidad; i++) {
        	for(int j=0; j<velocidad-(i-15); j++) {
        		x1+=Math.cos(angulo);
            	y1+=Math.sin(angulo);
        	}
        }
        donde_caera[0]=x1;
        donde_caera[1]=y1;
        return donde_caera;
    }
    
    private double[] pos_frenada0(double velocidad) {
    	double angulo = futbol.General.getAngulo(bola_vieja.getX(), bola_vieja.getY(), bola.getX(), bola.getY());
        double x1 = bola.getX();
        double y1 = bola.getY();
        double[] donde_caera = new double[2];
        
        for(int i=0; i<velocidad; i++) {
        	for(int j=0; j<velocidad-i; j++) {
        		x1+=Math.cos(angulo);
            	y1+=Math.sin(angulo);
        	}
        }
        donde_caera[0]=x1;
        donde_caera[1]=y1;
        return donde_caera;
    }
    
    // Predecir trayectoria
    private double dondeIraY() {
        double A1 = bola_vieja.getY()-bola.getY();
        double B1 = bola.getX()-bola_vieja.getX();
        double C1 = A1*bola.getX()+B1*bola.getY();
        
        double A2 = (-100)-100;
        double B2 = (-155)-(-155);
        double C2 = A2*(-155)+B2*100;
        
        double x = 0;
        double y = 0;
        double det = A1*B2 - A2*B1;
        
        if(det != 0){
            x = (B2*C1 - B1*C2)/det;
            y = (A1*C2 - A2*C1)/det;
        }

        return y;
    }
    
    
    //Modificado por la organizacio. No debe visualizar nada.
    private void dibujar_matriz() {
    	/*System.out.println("--------------------------------------------------------");
		for(int j=0; j<zonay; j++) {
			for(int i=0; i<zonax; i++)
				if(i==posjx && j==posjy)
					System.out.print(""+"XX"+"");
				else if(zonas[i][j]==-1)
					System.out.print(""+"__"+"");
				else if(zonas[i][j]<10)
					System.out.print(" "+zonas[i][j]+"");
				else
					System.out.print(""+zonas[i][j]+"");
			System.out.println();
		}*/
	}
    
    
    // Busqueda de caminos
    public int buscarCamino(int empx, int empy) {
    	//System.out.println("Buscando uno...");
    	abiertos.clear();
		cerrados.clear();

		// Mostrar Mapa de la Matriz
		//dibujar_matriz();

		zonas[empx][empy]=0;
		
		nodo A = new nodo(empx,empy,0,0);
		abiertos.add(A);
		examinar_alrededores(A);
		cerrados.add(A);
		abiertos.remove(A);
		
		int ciclos=1;
		boolean fin = false;
		boolean no_encontrado = false;
		
		if(abiertos.size()==0) {
			fin=true;
			no_encontrado = true;
			//System.out.println("Camino no encontrado!!!");
		}
		
		while(fin==false) {
			A=elegir_mejorF();
			cerrados.add(A);
			abiertos.remove(A);
			examinar_alrededores(A);
			fin=comprobar_sifin();
			if(abiertos.size()==0) {
				fin=true;
				no_encontrado = true;
				//System.out.println("Camino no encontrado!!!");
			}
			ciclos++;
		}
		
		//System.out.println("Ciclos = "+ciclos);
		int lado = -1;
		if(no_encontrado==false) lado = crear_camino(empx, empy);
		//System.out.println("Empezar hacia: "+lado);
		return lado;
    }
    

    public void examinar_alrededores(nodo n) {
		if(n.x>0) {
			if(zonas[n.x-1][n.y]==-1) nuevoNodo(n.x-1,n.y,n,10);
			if(n.y>0) if(zonas[n.x-1][n.y-1]==0) nuevoNodo(n.x-1,n.y-1,n,14);
			if(n.y<zonay-1) if(zonas[n.x-1][n.y+1]==0) nuevoNodo(n.x-1,n.y+1,n,14);
		}
		if(n.x<zonax-1) {
			if(zonas[n.x+1][n.y]==-1) nuevoNodo(n.x+1,n.y,n,10);
			if(n.y>0) if(zonas[n.x+1][n.y-1]==0) nuevoNodo(n.x+1,n.y-1,n,14);
			if(n.y<zonay-1) if(zonas[n.x+1][n.y+1]==0) nuevoNodo(n.x+1,n.y+1,n,14);
		}
		if(n.y>0) if(zonas[n.x][n.y-1]==-1) nuevoNodo(n.x,n.y-1,n,10);
		if(n.y<zonay-1) if(zonas[n.x][n.y+1]==-1) nuevoNodo(n.x,n.y+1,n,10);
	}

	public void nuevoNodo(int x, int y, nodo padre, int peso) {
		//System.out.print("Verificando - ("+x+","+y+") ");
		
		// Comprobar si estaba en la lista abiertos
		boolean existe=false;
		int j=0;
		while(j<abiertos.size() && existe==false) {
			nodo existente = abiertos.get(j);
			if(existente.x==x && existente.y==y) existe=true;
			j++;
		}
		
		if(existe==true) {
			j--;
			nodo yaexistente = abiertos.get(j);
			//System.out.print("<-- ABIERTO");
			if(yaexistente.G > padre.G+peso) {
				//System.out.print(" - CAMBIA de "+yaexistente.F);
				yaexistente.F = (padre.G+peso)+yaexistente.H;
				yaexistente.padre = padre;
				//System.out.print(" a "+yaexistente.F);
			}
			//System.out.println();
		}

		if(existe==false) {
			// Comprobar si estaba en la lista de cerrados
			j=0;
			while(j<cerrados.size() && existe==false) {
				nodo cer = cerrados.get(j);
				if(cer.x== x && cer.y==y) {
					existe=true;
					//System.out.println("<-- CERRADO");
				}
				j++;
			}
		}
		
		if(existe==false) {
			int recorrido = 0;
			for(int i=x; i<buscax; i++)
				recorrido+=2;
			for(int i=x; i>buscax; i--)
				recorrido+=2;
			for(int i=y; i<buscay; i++)
				recorrido++;
			for(int i=y; i>buscay; i--)
				recorrido++;
			nodo nuevo = new nodo(x,y,padre.G+peso,recorrido*10);
			nuevo.padre = padre;
			abiertos.add(nuevo);
			//System.out.print(" ***NUEVO R="+recorrido);
			//System.out.println(" - F="+nuevo.F);
		}
		
	}

	public nodo elegir_mejorF() {
		 nodo mejor = null;
		 int mas_rapido = 9999;
		 for(int i=abiertos.size()-1; i>-1; i--) {
			 nodo provi = abiertos.get(i);
			 if(provi.F<mas_rapido) {
				 mejor = provi;
				 mas_rapido = provi.F;
			 }
		 }
		 //System.out.println("El mejor ha sido ("+mejor.x+","+mejor.y+")="+mejor.F);
		 //System.out.println();
		 return mejor;
	 }
	
	public boolean comprobar_sifin() {
		nodo n;
		boolean fin = false;
		//System.out.print("Abiertos: ");
		for(int i=0; i<abiertos.size() && fin==false; i++) {
			 n=abiertos.get(i);
			 //System.out.print("("+n.x+","+n.y+") ");
			 
			 if(n.x==buscax && n.y==buscay) {
				 //System.out.println("\nLLEGAMOS!!!");
				 fin = true;
			 }			 
			 
		 }
		 //System.out.println();
		 return fin;
	}
	
	private int crear_camino(int comx, int comy) {
		nodo ultimo = null;
		nodo penultimo = null;
		int lado=0;
		//System.out.println("Creando Camino...");
		for(int i=0; i<abiertos.size(); i++) {
			nodo provi = abiertos.get(i);
			if(provi.x==buscax && provi.y==buscay) {
				ultimo=provi;
			}
		}
		
		if(ultimo!=null) {
			//System.out.println("Entras?");
			while(ultimo.padre!=null) {
				//zonas[ultimo.x][ultimo.y]=3;
				penultimo = ultimo;
				ultimo = ultimo.padre;
			}
		}
		
		//System.out.println("Camino CREADOOOO!!!");
		//System.out.println("X="+penultimo.x);
		if(penultimo.x>comx) {
			lado=1;
			if(penultimo.y>comy) lado=2;
			else if(penultimo.y<comy) lado=8;
		} else {
			if(penultimo.y>comy) lado=3;
			if(penultimo.y<comy) lado=7;
		}
		
		if(penultimo.x<comx) {
			lado=5;
			if(penultimo.y>comy) lado=4;
			else if(penultimo.y<comy) lado=6;
		} else {
			if(penultimo.y>comy) lado=3;
			if(penultimo.y<comy) lado=7;
		}
		//System.out.println("*********!!!");
		return lado;
	}

    public class nodo {
    	public int x, y;
    	public int F, G, H;
    	public nodo padre;
    	
    	nodo(int px, int py, int pG, int pH) {
    		x=px; 
    		y=py; 
    		G=pG; 
    		H=pH;
    		F = G + H;
    		padre=null;
    	}
    }
    
    //Modificado por la organizacion. ¿Retardo?
    /*private void delayMilli(long ms) {
    	Date d = new Date();
    	Date e;
    	long cTime = d.getTime();
    	long tTime;

    	do {
    		e = new Date();
    		tTime = e.getTime();
    	} while(tTime - cTime <= ms);
    		return;
    }*/
    
}

